package com.weimob.mcloud.wechatwork.customer.third.tag;

import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import com.weimob.mcloud.wechatwork.core.adapter.enums.cdp.TagTypeEnum;
import com.weimob.mcloud.wechatwork.core.adapter.pojo.dto.bos.response.ProductInstanceDTO;
import com.weimob.mcloud.wechatwork.core.adapter.pojo.dto.cdp.request.tag.*;
import com.weimob.mcloud.wechatwork.core.adapter.pojo.dto.cdp.response.tag.TagAdapterBO;
import com.weimob.mcloud.wechatwork.core.adapter.pojo.dto.cdp.response.tag.TagGroupAdapterBO;
import com.weimob.mcloud.wechatwork.core.adapter.service.cdp.CdpTagAdapterService;
import com.weimob.mcloud.wechatwork.core.entity.privatesphere.PrivateSphere;
import com.weimob.mcloud.wechatwork.core.entity.relation.customer.Customer;
import com.weimob.mcloud.wechatwork.core.entity.relation.tag.Tag;
import com.weimob.mcloud.wechatwork.core.entity.relation.tag.TagDetail;
import com.weimob.mcloud.wechatwork.core.entity.relation.tag.TagGroup;
import com.weimob.mcloud.wechatwork.customer.convertor.bos.PrivateSphereCovert;
import com.weimob.mcloud.wechatwork.customer.convertor.tag.TagGroupConvert;
import com.weimob.mcloud.wechatwork.customer.service.user.base.PrivateSphereDTO;
import com.weimob.mcloud.wechatwork.customer.service.user.enums.TagSourceEnum;
import com.weimob.mcloud.wechatwork.customer.service.user.module.bo.tag.TagBO;
import com.weimob.mcloud.wechatwork.customer.service.user.module.bo.tag.TagGroupBO;
import com.weimob.mcloud.wechatwork.customer.service.user.module.dto.tag.TagDTO;
import com.weimob.mcloud.wechatwork.customer.service.user.module.dto.tag.TagGroupDTO;
import com.weimob.mcloud.wechatwork.customer.third.BosThird;
import com.weimob.soa.common.response.SoaResponse;
import com.weimob.soa.common.utils.SoaUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.*;

/**
 * <p>
 * 涉及与cdp标签的交互
 * </P>
 *
 * @author junlong.lv
 * @version 1.0
 * @date 2021/11/3 8:53 下午
 */
@Component
@Slf4j
public class CdpTagThird {

    @Autowired
    private CdpTagAdapterService cdpTagAdapterService;

    @Autowired
    private BosThird bosThird;

    /**
     * 创建cdp标签组
     *
     * @param TagGroupDTO
     * @return
     */
    public TagGroupBO createCdpTagGroup(TagGroupDTO TagGroupDTO) {

        PrivateSphereDTO privateSphereDTO = TagGroupDTO.getPrivateSphereDTO();
        PrivateSphere privateSphere = PrivateSphereCovert.toPrivateSphere(privateSphereDTO);
        Map<String, Object> extInfo = TagGroupDTO.getExtInfo();
        Object cdp_product_instance_id = extInfo.get("cdp_product_instance_id");
        Long cdpProductInstance = null;

        if (Objects.nonNull(cdp_product_instance_id)) {
            cdpProductInstance = (Long) cdp_product_instance_id;
        }

        Long rootVid = null;
        Object root_vid = extInfo.get("root_vid");
        if (Objects.nonNull(root_vid)) {
            rootVid = (Long) root_vid;
        }

        if (Objects.isNull(cdpProductInstance) || Objects.isNull(rootVid)) {
            return null;
        }
        TagGroupAdapterDTO tagGroupAdapterDTO = new TagGroupAdapterDTO();
        tagGroupAdapterDTO.setTagGroupName(TagGroupDTO.getTagGroupName());
        tagGroupAdapterDTO.setTagSource(TagSourceEnum.WECHAT.getSource());
        tagGroupAdapterDTO.setChannelProductInstanceId(cdpProductInstance);
        tagGroupAdapterDTO.setBosId(privateSphere.getBosId());
        tagGroupAdapterDTO.setVid(rootVid);
        tagGroupAdapterDTO.setCdpTagGroupId(TagGroupDTO.getCdpTagGroupId());
        log.info("调用cdp接口创建/编辑标签组, request:{}", JSON.toJSONString(tagGroupAdapterDTO));
        SoaResponse<TagGroupAdapterBO, ?> orEditCdpTagGroup = cdpTagAdapterService.createOrEditCdpTagGroup(tagGroupAdapterDTO);
        log.info("调用cdp接口创建/编辑标签组返回结果, request:{}, response:{}", JSON.toJSONString(tagGroupAdapterDTO), JSON.toJSONString(orEditCdpTagGroup));
        TagGroupAdapterBO unpack = SoaUtil.unpack(orEditCdpTagGroup);
        if (Objects.isNull(unpack)) {
            return null;
        }

        TagGroupBO tagGroupBO = new TagGroupBO();
        tagGroupBO.setCdpTagGroupId(unpack.getCdpTagGroupId());
        tagGroupBO.setTagGroupName(unpack.getTagGroupName());
        tagGroupBO.setTagSource(unpack.getTagSource());

        return tagGroupBO;
    }

    /**
     * 删除cdp标签组
     *
     * @param
     * @return
     */
    public Boolean deleteCdpTagGroup(Long cdpProductInstanceId, Long rootVid, Long bosId, String cdpTagGroupId) {

        TagGroupAdapterDTO tagGroupAdapterDTO = new TagGroupAdapterDTO();
        tagGroupAdapterDTO.setBosId(bosId);
        tagGroupAdapterDTO.setChannelProductInstanceId(cdpProductInstanceId);
        tagGroupAdapterDTO.setVid(rootVid);
        tagGroupAdapterDTO.setCdpTagGroupId(cdpTagGroupId);

        try {

            SoaResponse<Boolean, ?> booleanSoaResponse = cdpTagAdapterService.deleteCdpTagGroup(tagGroupAdapterDTO);
            log.info("调用cdp接口,删除cdp标签组, request:{}, response:{}", JSON.toJSONString(tagGroupAdapterDTO), JSON.toJSONString(booleanSoaResponse));
            return SoaUtil.unpack(booleanSoaResponse);
        } catch (Exception e) {

            TagBatchQueryReq tagBatchQueryReq = new TagBatchQueryReq();
            tagBatchQueryReq.setCdpTagGroupId(cdpTagGroupId);
            tagBatchQueryReq.setBosId(bosId);
            tagBatchQueryReq.setChannelProductInstanceId(cdpProductInstanceId);
            tagBatchQueryReq.setVid(rootVid);

            SoaResponse<TagGroupAdapterBO, ?> tagGroupAdapterBOSoaResponse = cdpTagAdapterService.queryTagByTagGroupId(tagBatchQueryReq);
            if (tagGroupAdapterBOSoaResponse.getReturnCode().equals("100001")) {
                return true;
            }
            TagGroupAdapterBO unpack = SoaUtil.unpack(tagGroupAdapterBOSoaResponse);
            if (Objects.isNull(unpack)) {
                return true;
            }

            return false;
        }
        
    }

    /**
     * 创建cdp标签
     *
     * @param tagDTO
     * @return
     */
    public TagBO createCdpTag(TagDTO tagDTO) {

        TagGroupDTO tagGroupDTO = tagDTO.getTagGroupDTO();
        PrivateSphereDTO privateSphereDTO = tagDTO.getPrivateSphereDTO();
        PrivateSphere privateSphere = PrivateSphereCovert.toPrivateSphere(privateSphereDTO);
        Map<String, Object> extInfo = tagDTO.getExtInfo();

        Object cdp_product_instance_id = extInfo.get("cdp_product_instance_id");
        Long cdpProductInstance = null;

        if (Objects.nonNull(cdp_product_instance_id)) {
            cdpProductInstance = (Long) cdp_product_instance_id;
        }

        Long rootVid = null;
        Object root_vid = extInfo.get("root_vid");
        if (Objects.nonNull(root_vid)) {
            rootVid = (Long) root_vid;
        }

        //TODO 其实这里不该抛异常
        if (Objects.isNull(cdpProductInstance) || Objects.isNull(rootVid)) {
            return null;
        }

        TagAdapterDTO tagAdapterDTO = new TagAdapterDTO();
        tagAdapterDTO.setTagName(tagDTO.getTagName());
        tagAdapterDTO.setCdpTagId(tagDTO.getCdpTagId());
        tagAdapterDTO.setBosId(privateSphere.getBosId());
        tagAdapterDTO.setTagSource(TagSourceEnum.WECHAT.getSource());
        tagAdapterDTO.setChannelProductInstanceId(cdpProductInstance);
        tagAdapterDTO.setVid(rootVid);

        TagGroupAdapterDTO tagGroupAdapterDTO = new TagGroupAdapterDTO();
        tagGroupAdapterDTO.setCdpTagGroupId(tagGroupDTO.getCdpTagGroupId());
        tagGroupAdapterDTO.setTagGroupName(tagGroupDTO.getTagGroupName());
        tagAdapterDTO.setTagGroupDTO(tagGroupAdapterDTO);
        log.info("调用cdp接口创建标签, request:{}", JSON.toJSONString(tagAdapterDTO));
        SoaResponse<TagAdapterBO, ?> tagAdapterBOSoaResponse = cdpTagAdapterService.createTag(tagAdapterDTO);
        log.info("调用cdp接口创建标签返回结果, request:{}, response:{}", JSON.toJSONString(tagAdapterDTO), JSON.toJSONString(tagAdapterBOSoaResponse));

        TagAdapterBO unpack = SoaUtil.unpack(tagAdapterBOSoaResponse);
        if (Objects.isNull(unpack)) {
            return null;
        }
        //TagGroupAdapterBO tagGroupBOResponse = unpack.getTagGroupBO();
        TagGroupBO tagGroupBO = new TagGroupBO();
        tagGroupBO.setCdpTagGroupId(tagGroupDTO.getCdpTagGroupId());
        tagGroupBO.setTagGroupName(tagGroupDTO.getTagGroupName());

        TagBO tagBO = new TagBO();
        tagBO.setTagGroupBO(tagGroupBO);
        tagBO.setCdpTagId(unpack.getCdpTagId());
        tagBO.setTagName(unpack.getTagName());
        tagBO.setTagSource(unpack.getTagSource());

        return tagBO;
    }

    /**
     * 编辑cdp标签
     *
     * @param tagDTO
     * @return
     */
    public Boolean updateCdpTag(TagDTO tagDTO) {

        TagGroupDTO tagGroupDTO = tagDTO.getTagGroupDTO();
        PrivateSphereDTO privateSphereDTO = tagDTO.getPrivateSphereDTO();
        PrivateSphere privateSphere = PrivateSphereCovert.toPrivateSphere(privateSphereDTO);
        Map<String, Object> extInfo = tagDTO.getExtInfo();

        Object cdp_product_instance_id = extInfo.get("cdp_product_instance_id");
        Long cdpProductInstance = null;

        if (Objects.nonNull(cdp_product_instance_id)) {
            cdpProductInstance = (Long) cdp_product_instance_id;
        }

        Long rootVid = null;
        Object root_vid = extInfo.get("root_vid");
        if (Objects.nonNull(root_vid)) {
            rootVid = (Long) root_vid;
        }

        if (Objects.isNull(cdpProductInstance) || Objects.isNull(rootVid)) {
            return false;
        }

        TagAdapterDTO tagAdapterDTO = new TagAdapterDTO();
        tagAdapterDTO.setTagName(tagDTO.getTagName());
        tagAdapterDTO.setCdpTagId(tagDTO.getCdpTagId());
        tagAdapterDTO.setBosId(privateSphere.getBosId());
        tagAdapterDTO.setTagSource(TagSourceEnum.WECHAT.getSource());
        tagAdapterDTO.setChannelProductInstanceId(cdpProductInstance);
        tagAdapterDTO.setVid(rootVid);

        TagGroupAdapterDTO tagGroupAdapterDTO = new TagGroupAdapterDTO();
        tagGroupAdapterDTO.setCdpTagGroupId(tagGroupDTO.getCdpTagGroupId());
        tagGroupAdapterDTO.setTagGroupName(tagGroupDTO.getTagGroupName());
        tagAdapterDTO.setTagGroupDTO(tagGroupAdapterDTO);

        SoaResponse<Boolean, ?> booleanSoaResponse = cdpTagAdapterService.editTag(tagAdapterDTO);
        log.info("调用cdp接口编辑标签, request:{}, response:{}", JSON.toJSONString(tagAdapterDTO), JSON.toJSONString(booleanSoaResponse));
        return SoaUtil.unpack(booleanSoaResponse);
    }

    /**
     * 删除cdp标签
     *
     * @param
     * @return
     */
    public Boolean deleteCdpTag(TagAdapterDTO tagAdapterDTO) {
        SoaResponse<Boolean, ?> booleanSoaResponse = cdpTagAdapterService.deleteTag(tagAdapterDTO);
        log.info("调用cdp接口删除cdp标签, request:{}, response:{}", JSON.toJSONString(tagAdapterDTO), JSON.toJSONString(booleanSoaResponse));
        return SoaUtil.unpack(booleanSoaResponse);
    }

    public Boolean deleteCdpTag(Long cdpProductInstanceId, Long rootVid, Long bosId,  List<String> cdpTagIds, String cdpTagGroupId) {
        if (CollectionUtils.isEmpty(cdpTagIds)) {
            return false;
        }

        //先联调吧
        for (String cdpTagId : cdpTagIds) {
            TagAdapterDTO tagAdapterDTO = new TagAdapterDTO();
            tagAdapterDTO.setBosId(bosId);
            tagAdapterDTO.setChannelProductInstanceId(cdpProductInstanceId);
            tagAdapterDTO.setVid(rootVid);

            tagAdapterDTO.setCdpTagId(cdpTagId);
            TagGroupAdapterDTO tagGroupAdapterDTO = new TagGroupAdapterDTO();
            tagGroupAdapterDTO.setCdpTagGroupId(cdpTagGroupId);

            tagAdapterDTO.setTagGroupDTO(tagGroupAdapterDTO);

            deleteCdpTag(tagAdapterDTO);
        }


        return true;
    }

    public Boolean batchAddCdpCustomerTag(List<TagDetail> tagDetailList, Long bosId) {

        List<ProductInstanceDTO> productInstanceDTOS = bosThird.queryProductInstanceDTO(bosId, Lists.newArrayList(204L));
        if (CollectionUtils.isEmpty(productInstanceDTOS)) {
            return false;
        }

        //获取cdp产品实例id
        ProductInstanceDTO cdpProductInstanceDTO = productInstanceDTOS.get(0);

        //查询bosId下根节点vid
        Long rootVid = bosThird.queryRootVidByBosId(bosId);

        for (TagDetail tagDetail : tagDetailList) {
            addCdpCustomerTag(tagDetail, bosId, rootVid, cdpProductInstanceDTO.getProductInstanceId());
        }
        return true;
    }

    public Boolean batchDeleteCustomerTag(List<TagDetail> tagDetailList, Long bosId) {
        if (CollectionUtils.isEmpty(tagDetailList)) {
            return false;
        }

        List<ProductInstanceDTO> productInstanceDTOS = bosThird.queryProductInstanceDTO(bosId, Lists.newArrayList(204L));
        if (CollectionUtils.isEmpty(productInstanceDTOS)) {
            return false;
        }

        //获取cdp产品实例id
        ProductInstanceDTO cdpProductInstanceDTO = productInstanceDTOS.get(0);

        //查询bosId下根节点vid
        Long rootVid = bosThird.queryRootVidByBosId(bosId);

        for (TagDetail tagDetail : tagDetailList) {
            try {
                deleteCdpCustomerTag(tagDetail, bosId, rootVid, cdpProductInstanceDTO.getProductInstanceId());
            } catch (Exception e) {
                log.error("删除cdp客户标签失败, bosId:{}, rootVid:{}, productInstanceId:{}, tagDetails:{}, error:{}",
                        bosId, rootVid, cdpProductInstanceDTO.getProductInstanceId(), JSON.toJSONString(tagDetail), e);
            }

        }
        return true;
    }

    public Boolean addCdpCustomerTag(TagDetail tagDetail, Long bosId, Long rootVid, Long cdpProductInstanceId) {

        CustomerTagAdapterDTO customerTagAdapterDTO = new CustomerTagAdapterDTO();
        customerTagAdapterDTO.setBosId(bosId);
        customerTagAdapterDTO.setVid(rootVid);
        customerTagAdapterDTO.setChannelProductInstanceId(cdpProductInstanceId);

        Customer customer = tagDetail.getCustomer();
        customerTagAdapterDTO.setWid(customer.getWid());

        Tag tag = tagDetail.getTag();
        TagGroup tagGroup = tag.getTagGroup();


        TagGroupAdapterDTO tagGroupAdapterDTO = new TagGroupAdapterDTO();
        tagGroupAdapterDTO.setCdpTagGroupId(tagGroup.getCdpTagGroupId());
        tagGroupAdapterDTO.setTagSource(tagGroup.getTagSource());


        TagAdapterDTO tagAdapterDTO = new TagAdapterDTO();
        tagAdapterDTO.setTagGroupDTO(tagGroupAdapterDTO);
        tagAdapterDTO.setCdpTagId(tag.getCdpTagId());
        tagAdapterDTO.setTagSource(tag.getTagSource());

        customerTagAdapterDTO.setTagDTO(tagAdapterDTO);
        log.info("同步客户标签关系到cdp, request:{}", JSON.toJSONString(customerTagAdapterDTO));
        SoaResponse<Boolean, ?> customerTag = cdpTagAdapterService.createCustomerTag(customerTagAdapterDTO);
        log.info("同步客户标签关系到cdp, 同步结果, request:{}, response:{}", JSON.toJSONString(customerTagAdapterDTO), JSON.toJSONString(customerTag));


        return SoaUtil.unpack(customerTag);
    }

    public Boolean deleteCdpCustomerTag(TagDetail tagDetail, Long bosId, Long rootVid, Long cdpProductInstanceId) {
        CustomerTagAdapterDTO customerTagAdapterDTO = new CustomerTagAdapterDTO();
        customerTagAdapterDTO.setBosId(bosId);
        customerTagAdapterDTO.setVid(rootVid);
        customerTagAdapterDTO.setChannelProductInstanceId(cdpProductInstanceId);

        Customer customer = tagDetail.getCustomer();
        customerTagAdapterDTO.setWid(customer.getWid());

        Tag tag = tagDetail.getTag();
        TagGroup tagGroup = tag.getTagGroup();


        TagGroupAdapterDTO tagGroupAdapterDTO = new TagGroupAdapterDTO();
        tagGroupAdapterDTO.setCdpTagGroupId(tagGroup.getCdpTagGroupId());
        tagGroupAdapterDTO.setTagSource(tagGroup.getTagSource());


        TagAdapterDTO tagAdapterDTO = new TagAdapterDTO();
        tagAdapterDTO.setTagGroupDTO(tagGroupAdapterDTO);
        tagAdapterDTO.setCdpTagId(tag.getCdpTagId());
        tagAdapterDTO.setTagSource(tag.getTagSource());

        customerTagAdapterDTO.setTagDTO(tagAdapterDTO);
        SoaResponse<Boolean, ?> customerTag = cdpTagAdapterService.removeCustomerTag(customerTagAdapterDTO);


        return SoaUtil.unpack(customerTag);
    }

    /**
     *
     * @param bosId
     * @param cdpProductInstanceId
     * @param vid
     * @return
     */
    public List<TagGroupBO> queryAllTag(Long bosId, Long cdpProductInstanceId, Long vid) {

        TagAdapterDTO tagAdapterDTO = new TagAdapterDTO();
        tagAdapterDTO.setBosId(bosId);
        tagAdapterDTO.setChannelProductInstanceId(cdpProductInstanceId);
        tagAdapterDTO.setVid(vid);


        List<Integer> tagTypes = new ArrayList<>();
        tagTypes.add(TagTypeEnum.MULTIPLE_Choices.getType());
        tagTypes.add(TagTypeEnum.SINGLE_CHOICES.getType());
        tagTypes.add(TagTypeEnum.TEXT.getType());
        tagAdapterDTO.setTagTypes(tagTypes);

        SoaResponse<List<TagGroupAdapterBO>, ?> listSoaResponse = cdpTagAdapterService.queryAllTag(tagAdapterDTO);
        List<TagGroupAdapterBO> tagGroupAdapterBOS = SoaUtil.unpack(listSoaResponse);
        if (CollectionUtils.isEmpty(tagGroupAdapterBOS)) {
            return new ArrayList<>();
        }

        return TagGroupConvert.toTagGroupBOFromAdapter(tagGroupAdapterBOS);
    }

    public List<TagGroupBO> queryCustomerTag(Long bosId, Long cdpProductInstanceId, Long rootVid, Long wid) {

        CustomerTagAdapterDTO customerTagAdapterDTO = new CustomerTagAdapterDTO();
        customerTagAdapterDTO.setWid(wid);
        customerTagAdapterDTO.setBosId(bosId);
        customerTagAdapterDTO.setVid(rootVid);
        customerTagAdapterDTO.setChannelProductInstanceId(cdpProductInstanceId);

        SoaResponse<List<TagGroupAdapterBO>, ?> soaResponse = cdpTagAdapterService.queryCustomerTag(customerTagAdapterDTO);
        List<TagGroupAdapterBO> tagGroupAdapterBOS = SoaUtil.unpack(soaResponse);
        if (CollectionUtils.isEmpty(tagGroupAdapterBOS)) {
            return new ArrayList<>();
        }

        return TagGroupConvert.toTagGroupBOFromAdapter(tagGroupAdapterBOS);
    }

    public List<TagGroupBO> queryTagByCdpTagIds(Long bosId, Map<String, Set<String>> tagIdMap) {
        if (MapUtils.isEmpty(tagIdMap)) {
            return new ArrayList<>();
        }

        Long rootVid = bosThird.queryRootVidByBosId(bosId);
        ProductInstanceDTO cdpProductInstance = bosThird.getCdpProductInstance(bosId);
        if (Objects.isNull(cdpProductInstance) || Objects.isNull(rootVid)) {
            return new ArrayList<>();
        }

        TagInfoQueryDTO tagInfoQueryDTO = new TagInfoQueryDTO();
        tagInfoQueryDTO.setBosId(bosId);
        tagInfoQueryDTO.setChannelProductInstanceId(cdpProductInstance.getProductInstanceId());
        tagInfoQueryDTO.setVid(rootVid);

        List<TagGroupAdapterDTO> tagGroupList = new ArrayList<>();

        for (Map.Entry<String, Set<String>> entry : tagIdMap.entrySet()){

            Set<String> cdpTagIds = entry.getValue();
            if (CollectionUtils.isEmpty(cdpTagIds)) {
                continue;
            }

            List<TagAdapterDTO> tagList = new ArrayList<>();
            for (String cdpTagId : entry.getValue()) {
                TagAdapterDTO tagAdapterDTO = new TagAdapterDTO();
                tagAdapterDTO.setCdpTagId(cdpTagId);
                tagList.add(tagAdapterDTO);
            }


            TagGroupAdapterDTO tagGroupAdapterDTO = new TagGroupAdapterDTO();
            tagGroupAdapterDTO.setCdpTagGroupId(entry.getKey());
            tagGroupAdapterDTO.setTagList(tagList);


            tagGroupList.add(tagGroupAdapterDTO);
        }

        tagInfoQueryDTO.setTagGroupList(tagGroupList);
        log.info("根据cdp标签id批量查询标签信息, request:{}", JSON.toJSONString(tagInfoQueryDTO));
        SoaResponse<List<TagGroupAdapterBO>, ?> soaResponse = cdpTagAdapterService.queryTag(tagInfoQueryDTO);
        log.info("根据cdp标签id批量查询标签信息返回结果, request:{}, response:{}", JSON.toJSONString(tagInfoQueryDTO), JSON.toJSONString(soaResponse));
        List<TagGroupAdapterBO> unpack = SoaUtil.unpack(soaResponse);

        return TagGroupConvert.toTagGroupBOFromAdapter(unpack);
    }

}
